#include"../include/common.h"




int recvmasge(int netfd,TLVMsg *msg)
{
    bzero(msg,sizeof(TLVMsg));
    int rest=0;
    rest=recv(netfd,&msg->type,sizeof(int),MSG_WAITALL);
    if(rest==0)
    {
        return -1;
    }
    rest=recv(netfd,&msg->value_len,sizeof(int),MSG_WAITALL);
    if(rest==0)
    {
        return -1;
    }
    rest=recv(netfd,&msg->value,msg->value_len,MSG_WAITALL);
    if(rest==0)
    {
        return -1;
    }

    // msg->value[msg->value_len]='\0'; //确保字符串结束
    printf("收到消息：type=%d, value_len=%d, value=%s\n", msg->type, msg->value_len, msg->value);
    return 0;

}

int sendmasge(int netfd,int cont, int len,char *buf)
{
    TLVMsg sendmsg;
    bzero(&sendmsg,sizeof(TLVMsg));
    sendmsg.type=cont;
    sendmsg.value_len=len;
    memcpy(sendmsg.value, buf, len);
    sendmsg.value[sendmsg.value_len]='\0';

    send(netfd,&sendmsg.type,sizeof(int),MSG_NOSIGNAL);
    send(netfd,&sendmsg.value_len,sizeof(int),MSG_NOSIGNAL);
    send(netfd,&sendmsg.value,sendmsg.value_len,MSG_NOSIGNAL);
    printf("type:%d,len:%d,value:%s\n",sendmsg.type,sendmsg.value_len,sendmsg.value);
    return 0;

}
int login_in(int netfd,char *username,char *passwd,TLVMsg *msg, path_t *path,threadpool_t *threadpool)
{
        while(1){
            if(recvmasge(netfd,msg)!=0){
                close(netfd);
                return 0;
            };

            memcpy(username,msg->value,msg->type);
            username[msg->value_len]='\0';
            username[strcspn(username, "\r\n")] = '\0';
            printf("username=%s\n",msg->value);
            if(recvmasge(netfd,&msg)!=0){
                close(netfd);
                return 0;
            };
            strncpy(passwd,msg->value,msg->value_len);
            passwd[msg->value_len]='\0';
            passwd[strcspn(passwd, "\r\n")] = '\0';
            printf("passwd=%s\n",msg->value);
            if(msg->type==CMD_LOGIN)
            {
                char error_buf[1024] = {0};
                int sret=login_auth(username,passwd,error_buf,sizeof(error_buf));
                printf("sret=%d,error_buf=%s\n",sret,error_buf);
                if(sret==0){
                    printf("登录成功\n");
                    char str[]="login in succes";
                    // sendmasge(netfd,CMD_LOGIN,strlen(str),str);
                    sendmasge(netfd,0,strlen(str),str);
                    printf("sadfghnm\n");
                    init_user_path(&path,username);
                    PRINT_LOG_FILE(threadpool->logfd,username,8, "login succes",path->virtualPath,threadpool->mutex);
                    break;
                }else{                
                    
                    sendmasge(netfd,15,strlen(error_buf),error_buf);
                }
            }else{
                printf("需要sudo才能打开权限才能读取 /etc/shadow 文件\n");
                char str1[]="plese login ";
                sendmasge(netfd,15,strlen(str1),str1);
                PRINT_LOG_FILE(threadpool->logfd,username,8, "login filed",path->virtualPath,threadpool->mutex);
            }
        }
}


void *worker_function(void *arg)
{
    threadpool_t * threadpool = (threadpool_t *)arg;
    TLVMsg msg;
    int netfd=0;
    char error_buf[1024];
    char buf[1024];
    path_t path;
    init_path(&path);
    int sret=0;
    char username[20];
    char passwd[20];
    // printf("虚拟路径: %s\n", path.virtualPath);
    // printf("真实路径: %s\n", path.realPath);
    // printf("初始路径: %s\n", path.initPath);
    int ssret=-1;
    while (1)
    {
        pthread_mutex_lock(&threadpool->mutex);
        while (threadpool->queue.cond == 0)
        {
            pthread_cond_wait(&threadpool->cond, &threadpool->mutex);
        }
        netfd=threadpool->queue.head->fd;
        del_queue(&threadpool->queue);
        pthread_mutex_unlock(&threadpool->mutex);

        //1.进行登录
        while(1){
            ssret=recvmasge(netfd,&msg);
            if(ssret!=0){
                close(netfd);
                break;
            };

            memcpy(username,msg.value,msg.value_len);
            username[msg.value_len]='\0';
            username[strcspn(username, "\r\n")] = '\0';
            printf("username=%s\n",msg.value);
            ssret=recvmasge(netfd,&msg);
            if(ssret!=0){
                close(netfd);
                break;
            };
            strncpy(passwd,msg.value,msg.value_len);
            passwd[msg.value_len]='\0';
            passwd[strcspn(passwd, "\r\n")] = '\0';
            printf("passwd=%s\n",msg.value);
            if(msg.type==CMD_LOGIN)
            {
                sret=login_auth(username,passwd,error_buf,sizeof(error_buf));
                printf("sret=%d,error_buf=%s\n",sret,error_buf);
                if(sret==0){
                    printf("登录成功\n");
                    char str[]="login in succes";
                    // sendmasge(netfd,CMD_LOGIN,strlen(str),str);
                    sendmasge(netfd,CMD_LOGIN,strlen(str),str);
                    printf("sadfghnm\n");
                    init_user_path(&path,username);
                    PRINT_LOG_FILE(threadpool->logfd,username,8, "login succes",path.virtualPath,threadpool->mutex);
                    break;
                }else{                
                    
                    sendmasge(netfd,15,strlen(error_buf),error_buf);
                }
            }else{
                printf("需要sudo才能打开权限才能读取 /etc/shadow 文件\n");
                char str1[]="plese login ";
                sendmasge(netfd,15,strlen(str1),str1);
                PRINT_LOG_FILE(threadpool->logfd,username,8, "login filed",path.virtualPath,threadpool->mutex);
            }
        }

        while(1){
            if(ssret!=0){
                close(netfd);
                break;
            };
            
            if(username==NULL && passwd==NULL)
            {
                sendmasge(netfd,10,strlen("请登录用户"),"请登录用户");
            }

            printf("虚拟路径: %s\n", path.virtualPath);
            printf("真实路径: %s\n", path.realPath);
            printf("初始路径: %s\n", path.initPath);
            bzero(&msg,sizeof(msg));
            ssret=recvmasge(netfd,&msg);
            if(ssret!=0){
                close(netfd);
                break;
            };
            printf("处理消息：type=%d, value_len=%d, value=%s\n", msg.type, msg.value_len, msg.value);
            switch (msg.type)
            {
            case(CMD_INVALID): // 无效命令
                sendmasge(netfd, 0, strlen("invalid command"), "invalid command");
                break;
            case(CMD_CD):// 切换目录
                printf("this is cd \n");
                bzero(error_buf,sizeof(error_buf));
                sret=handle_cd(&path, msg.value,error_buf,sizeof(error_buf));
                printf("虚拟路径: %s\n", path.virtualPath);
                if(sret==0)
                {
                    printf("虚拟路径:%s\n", path.virtualPath);
                    sendmasge(netfd, CMD_CD,strlen(path.virtualPath), path.virtualPath);
                    PRINT_LOG_FILE(threadpool->logfd,username, 1, "success cd",path.virtualPath,threadpool->mutex);
                }else{
                    printf("错误: %s\n", error_buf);
                    sendmasge(netfd, CMD_CD, strlen(error_buf), error_buf);
                    PRINT_LOG_FILE(threadpool->logfd,username, 1, "failed cd",path.virtualPath,threadpool->mutex);
                }
                break;     
            case(CMD_LS): // 列出文件
                printf("this is ls \n");
                strncpy(msg.value,path.virtualPath,sizeof(msg.value));
                bzero(buf,sizeof(buf));
                sret=handle_ls(&path, msg.value, buf, sizeof(buf));
                if(sret == 0) {
                    printf("ls 输出:\n%s", buf);
                    printf("ls %ld --buf=%s\n",strlen(buf),buf);
                    sendmasge(netfd, CMD_LS, strlen(buf), buf);
                    PRINT_LOG_FILE(threadpool->logfd,username, 2, "success ls",path.virtualPath,threadpool->mutex);
                } else {
                    printf("handle_ls 失败: %s\n", buf);
                    PRINT_LOG_FILE(threadpool->logfd,username, 2, "failed ls",buf,threadpool->mutex);
                }
                break;    
            case(CMD_PUTS):// 上传文件
                sendmasge(netfd, CMD_PUTS, msg.value_len, msg.value);
                bzero(&msg,sizeof(TLVMsg));
                recvn(netfd,&msg.value_len,sizeof(msg.value_len));
                recvn(netfd,msg.value,msg.value_len);
                char path_r[1024];
                snprintf(path_r,sizeof(path_r),"%s/%s",path.realPath,msg.value);
                recvfile_fd(netfd,path_r);
                // recvfile(netfd);
                sendmasge(netfd, CMD_PUTS,strlen("success puts"), "success puts");
                PRINT_LOG_FILE(threadpool->logfd,username, 3, "success puts",path.virtualPath,threadpool->mutex);
                break;     
            case(CMD_GETS):
                sendmasge(netfd, CMD_GETS, msg.value_len, msg.value);
                bzero(path_r,sizeof(path_r));
                snprintf(path_r,sizeof(path_r),"%s/%s",path.realPath,msg.value);
                transfile(path_r,netfd);
                PRINT_LOG_FILE(threadpool->logfd,username, 3, "success gets",path.virtualPath,threadpool->mutex);
                break;     // 下载文件
            case(CMD_REMOVE):
                sret=handle_remove(&path,msg.value, error_buf, sizeof(error_buf));
                if(sret == 0) {
                    sendmasge(netfd, CMD_REMOVE, strlen("remove success"), "remove success");
                    PRINT_LOG_FILE(threadpool->logfd,username, 4, "success remove",path.virtualPath,threadpool->mutex);
                } else {
                    sendmasge(netfd, CMD_REMOVE, strlen(error_buf), error_buf);
                    printf("buf=%s",error_buf);
                    PRINT_LOG_FILE(threadpool->logfd,username, 4, "failed remove",error_buf,threadpool->mutex);
                }
                break;     // 删除文件
            case(CMD_PWD):
                bzero(buf,sizeof(buf));
                sret=handle_pwd(&path, buf, sizeof(buf));
                if(sret==0){
                    sendmasge(netfd, CMD_PWD, strlen(buf), buf);
                    PRINT_LOG_FILE(threadpool->logfd,username, 4, "success pwd",buf,threadpool->mutex);
                }else{
                    PRINT_LOG_FILE(threadpool->logfd,username, 4, "failed pwd","获取虚拟路径失败",threadpool->mutex);
                }
                break;     // 显示路径
            case(CMD_MKDIR):
                bzero(buf,sizeof(buf));
                sret=handle_mkdir(&path,msg.value, buf, sizeof(buf));
                if(sret==0){
                    sendmasge(netfd, CMD_MKDIR, strlen("mkdir success"), "mkdir success");
                    PRINT_LOG_FILE(threadpool->logfd,username, 5, "success mkdir",path.virtualPath,threadpool->mutex);
                    break;     // 创建目录
                }else
                {
                    PRINT_LOG_FILE(threadpool->logfd,username, 5, "file mkdir",msg.value,threadpool->mutex);
                    break;
                }                                   
            case(CMD_LOGIN):// 登录认证
                login_in(netfd,username,passwd,&msg, &path,&threadpool);
                // bzero(username,sizeof(username));
                // if(recvmasge(netfd,&msg)!=0){
                //     close(netfd);
                //     return 0;
                // };
                // strncpy(username,msg.value,msg.value_len);
                // username[msg.value_len]='\0';
                // username[strcspn(username, "\r\n")] = '\0';
                // if(recvmasge(netfd,&msg)!=0){
                //     close(netfd);
                //     return 0;
                // };
                // bzero(passwd,sizeof(passwd));
                // strncpy(passwd,msg.value,msg.value_len);
                // passwd[msg.value_len]='\0';
                // passwd[strcspn(passwd, "\r\n")] = '\0';
                // sret=login_auth(username,passwd,error_buf,sizeof(buf));
                // if(sret==0)
                // {
                //     printf("pool_t * threadpool)登录成功\n");
                //     sendmasge(netfd,CMD_LOGIN,sizeof("登录成功"),"登录成功");
                //     init_user_path(&path,username);
                //     break;
                // }else{
                //     sendmasge(netfd,CMD_LOGIN,strlen(error_buf),error_buf);
                // }
                break;     
            case(CMD_LOGOUT):// 登出
                bzero(username,sizeof(username));
                bzero(passwd,sizeof(passwd));
                init_path(&path);
                char str_r[]="Please log in again.";
                sendmasge(netfd,CMD_LOGIN,strlen(str_r),str_r);
                break;     
            case(CMD_RESUME):// 断点续传
                bzero(&msg,sizeof(msg));
                ssret=recvmasge(netfd,&msg);
                if(ssret!=0){
                    close(netfd);
                    break;
                };
                transfile(msg.value,netfd);
                break;    
            case(CMD_LOG):
                sendmasge(netfd, CMD_LOG, msg.value_len, msg.value);
                transfile("../log/log.txt",netfd);
                PRINT_LOG_FILE(threadpool->logfd,username, 3, "success gets",path.virtualPath,threadpool->mutex);
                break;     // 查看日志（可选)
            case(CMD_QUIT):
                close(netfd);
               
                break; // 客户端退出
            case(CMD_RMDIR):
                sret=handle_rmdir(&path,msg.value, error_buf, sizeof(error_buf));
                if(sret == 0) {
                    sendmasge(netfd, CMD_REMOVE, strlen("rmdir success"), "rmdir success");
                    PRINT_LOG_FILE(threadpool->logfd,username, 4, "success rmdir",path.virtualPath,threadpool->mutex);
                } else {
                    sendmasge(netfd, CMD_REMOVE, strlen(error_buf), error_buf);
                    printf("buf=%s",error_buf);
                    PRINT_LOG_FILE(threadpool->logfd,username, 4, "failed rmdir",error_buf,threadpool->mutex);
                }
                break; 
            default:
                continue;
            }

        }
        close(netfd);
        printf("关闭连接: %d\n", netfd);
    }
}



int creat_worker(threadpool_t * threadpool)
{
    for(int i = 0; i < threadpool->thread_arr.workNum; i++)
    {
        pthread_create(&threadpool->thread_arr.threadtid[i], NULL, worker_function, threadpool);
    }

    return 0;

}
